#ifndef _C_MEMORY_MANAGER_H_
#define _C_MEMORY_MANAGER_H_

#include <cstdlib>
#include <string>
#include <map>
#include <fstream>
#include <stack>
#include "cMacros.h"

using namespace std;

namespace common {

//------------------------------------------------------------
struct CBlock
{
  /// size allocated
  size_t         m_iSize;
  /// file containing the allocation
  string         m_sFile;
  /// allocation line
  int            m_iLine;
  bool           m_bIsArray;
};

//------------------------------------------------------------
class cEXPORT CMemoryManager
{
public :
  void*	cCALL  _alloc			  (size_t iSize, const string& sFile, int iLine, bool bIsArray);
	void	cCALL  _free			    (void* pPtr, bool bIsArray);
  void	cCALL  nextDelete		(const string& sFile, int iLine);
	//static CMemoryManager&  instance      ();
  void  cCALL  reportLeaks   ();
  CMemoryManager();
  ~CMemoryManager();
private :
  static const char*    s_pOutputFilePath;

  typedef std::map<void*, CBlock> CBlockMap;

  CBlockMap           m_Blocks;
  ofstream            m_OutputFile;
  stack<CBlock>       m_DeleteStack;
};

extern cEXPORT CMemoryManager g_memoryManager;

//------------------------------------------------------------
#ifdef _DEBUG
/*
cEXPORT inline void* operator new(std::size_t iSize, const char* pFile, int iLine)
{
	return g_memoryManager._alloc(iSize, pFile, iLine, false);
}
cEXPORT inline void* operator new[](std::size_t iSize, const char* pFile, int iLine)
{
	return g_memoryManager._alloc(iSize, pFile, iLine, true);
}

inline void operator delete(void* pPtr)
{
	g_memoryManager._free(pPtr, false);
}
inline void operator delete[](void* pPtr)
{
	g_memoryManager._free(pPtr, true);
}

inline void operator delete(void* pPtr, const char* pFile, int iLine)
{
	g_memoryManager.nextDelete(pFile, iLine);
	g_memoryManager._free(pPtr, false);
}
inline void operator delete[](void* pPtr, const char* pFile, int iLine)
{
	g_memoryManager.nextDelete(pFile, iLine);
	g_memoryManager._free(pPtr, true);
}
#define new     new(__FILE__, __LINE__)
#define delete  g_memoryManager.nextDelete(__FILE__, __LINE__), delete
*/
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new( _CLIENT_BLOCK, __FILE__, __LINE__)

#endif

} // end namespace
#endif